package utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JsonMap {
    /**
     * 递归地移除JsonNode中的position字段
     * todo 传入position字段列表
     *
     * @param node
     */
    public static void removePositionFields(JsonNode node) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;

            // 移除当前对象的position字段
            objectNode.remove("Position");
            objectNode.remove("Imports");
//            objectNode.remove("Annotations");
            objectNode.remove("Package");
            objectNode.remove("FilePath");
            objectNode.remove("Module");
            objectNode.remove("LocalVariables");
            objectNode.remove("Parameters");
//            objectNode.remove("Fields");

            // 递归处理所有子节点
            objectNode.fields().forEachRemaining(entry -> {
                removePositionFields(entry.getValue());
            });
        } else if (node.isArray()) {
            // 处理数组中的每个元素
            for (JsonNode arrayElement : node) {
                removePositionFields(arrayElement);
            }
        }
        // 其他类型的节点不需要处理
    }

    /**
     * 递归处理所有节点
     *
     * @param currentNode  当前遍历的节点
     * @param topLevelNode 第一层节点容器（用于搜索同级节点）
     */
    public static void processChainNodes(JsonNode currentNode, JsonNode topLevelNode) {
        if (currentNode.isObject()) {
            ObjectNode objNode = (ObjectNode) currentNode;

            // 发现CHAIN类型节点
            if (objNode.has("Type") && "CHAIN".equals(objNode.get("Type").asText())) {
                String targetNodeName = objNode.get("NodeName").asText();

                // 在顶层查找所有匹配的节点
                List<JsonNode> matches = findTopLevelMatches(topLevelNode, targetNodeName);

                // 创建functions数组
                ArrayNode functions = objNode.putArray("functions");
                matches.forEach(match -> functions.add(match.deepCopy()));
            }

            // 递归处理子节点
            Iterator<JsonNode> elements = objNode.elements();
            while (elements.hasNext()) {
                processChainNodes(elements.next(), topLevelNode);
            }
        } else if (currentNode.isArray()) {
            for (JsonNode element : currentNode) {
                processChainNodes(element, topLevelNode);
            }
        }
    }

    /**
     * 拆分JSON节点并返回提取的新JSON数据
     *
     * @param root     原始JSON的根节点（必须是ObjectNode类型）
     * @param nodeName 需要提取的节点名称
     * @return 包含提取内容的新JSON节点，原始数据会被修改
     */
    public static List<JsonNode> splitNode(JsonNode root, String nodeName) {
        List<JsonNode> topLevelMatches = findTopLevelMatches(root, nodeName);
        List<JsonNode> jsonNodes = new ArrayList<>();
        for (JsonNode node : topLevelMatches){
            JsonNode jsonNode = node.deepCopy();
            jsonNodes.add(jsonNode);
        }
        return jsonNodes;
    }

    /**
     * 在第一层节点中查找匹配的NodeName
     */
    private static List<JsonNode> findTopLevelMatches(JsonNode topLevelNode, String targetName) {
        List<JsonNode> results = new ArrayList<>();

        if (topLevelNode.isObject()) {
            // 遍历所有直接子节点
            topLevelNode.fields().forEachRemaining(entry -> {
                JsonNode value = entry.getValue();
                if (value.isObject() &&
                        value.has("NodeName") &&
                        targetName.equals(value.get("NodeName").asText())) {
                    results.add(value);
                }
            });
        } else if (topLevelNode.isArray()) {
            // 处理数组形式的顶层结构
            for (JsonNode element : topLevelNode) {
                if (element.isObject() &&
                        element.has("NodeName") && (
                        (targetName + "Imp").equals(element.get("NodeName").asText())) || (targetName).equals(element.get("NodeName").asText())) {
                    results.add(element);
                }
            }
        }
        return results;
    }
}
